<?php

include_once dirname(__FILE__) . '/helpers.php';

/**
 * The base view from which all project views inherit.
 */
class SrsBaseView extends AgaviView
{
	const SLOT_LAYOUT_NAME = 'slot';

	/**
	 * @var SrsUser
	 */
	protected $user;

	/**
	 * @var AgaviResponse
	 */
	protected $response;

	public function initialize(AgaviExecutionContainer $container)
	{
		parent::initialize($container);

		$this->response = $this->getResponse();
		$this->user = $this->context->getUser();
	}

	/**
	 * Handles output types that are not handled elsewhere in the view. The
	 * default behavior is to simply throw an exception.
	 *
	 * @param      AgaviRequestDataHolder The request data associated with
	 *                                    this execution.
	 *
	 * @throws     AgaviViewException if the output type is not handled.
	 */
	public final function execute(AgaviRequestDataHolder $rd)
	{
		throw new AgaviViewException(sprintf(
			'The view "%1$s" does not implement an "execute%3$s()" method to serve '.
			'the output type "%2$s", and the base view "%4$s" does not implement an '.
			'"execute%3$s()" method to handle this situation.',
			get_class($this),
			$this->container->getOutputType()->getName(),
			ucfirst(strtolower($this->container->getOutputType()->getName())),
			get_class()
		));
	}

	/**
	 * Prepares the HTML output type.
	 *
	 * @param      AgaviRequestDataHolder The request data associated with
	 *                                    this execution.
	 * @param      string The layout to load.
	 * @return     SrsBaseView
	 */
	public function setupHtml(AgaviRequestDataHolder $rd, $layoutName = null)
	{
		if($layoutName === null && $this->getContainer()->getParameter('is_slot', false)) {
			// it is a slot, so we do not load the default layout, but a different one
			// otherwise, we could end up with an infinite loop
			$layoutName = self::SLOT_LAYOUT_NAME;
		}

		// now load the layout
		// this method returns an array containing the parameters that were declared on the layout (not on a layer!) in output_types.xml
		// you could use this, for instance, to automatically set a bunch of CSS or Javascript includes based on layout parameters -->
		$this->loadLayout($layoutName);

		return $this;
	}

	/**
	 * @return bool
	 *         TRUE if this view is executed as a slot; otherwise FALSE.
	 */
	protected function isSlot()
	{
		return $this->container->getParameter('is_slot', false);
	}

	/**
	 * Generate a formatted Agavi URL.
	 *
	 * @param  string? $route
	 * @param  array $params
	 * @param  array $options
	 * @return string
	 */
	protected function genUrl($route, array $params = array(), array $options = array())
	{
		return $this->context->getRouting()->gen($route, $params, $options);
	}

	/**
	 * @param  string $template
	 * @return SrsBaseView
	 */
	protected function setTemplate($template)
	{
		$this->getLayer('content')->setTemplate($template);

		return $this;
	}

	/**
	 * @param  string $route
	 * @param  array $params
	 * @param  array $options
	 */
	protected function redirect($route, array $params = array(), array $options = array())
	{
		$this->response->setRedirect($this->genUrl($route, $params, $options));
	}

	/**
	 * @param  string $url
	 */
	protected function redirectUrl($url)
	{
		$this->response->setRedirect($url);
	}

	/**
	 * @return AgaviExecutionContainer
	 */
	protected function forward($module, $action)
	{
		return $this->createForwardContainer($module, $action);
	}

	/**
	 * @return AgaviExecutionContainer
	 */
	protected function forward404()
	{
		return $this->forward(AgaviConfig::get('actions.error_404_module'), AgaviConfig::get('actions.error_404_action'));
	}

	/**
	 * @param  string $form
	 * @param  array<string,mixed> $data
	 * @return SrsBaseView
	 */
	protected function populate($form, $data)
	{
		$this->context->getRequest()->setAttribute('populate', array($form => $data), 'org.agavi.filter.FormPopulationFilter');

		return $this;
	}

  /**
   * @param  string $file
   * @param  string? $vendor
   * @return SrsBaseView
   */
  protected function addStyle($file, $vendor = null)
  {
    $path = AgaviConfig::get('app.path') . '/';

    if ($vendor)
    {
      $path .= 'vendor/' . $vendor . '/';
    }
    else
    {
      $path .= 'css/';
    }

    $path .= $file . '.css';

    $this->context->getRequest()->appendAttribute('stylesheets', $path);

    return $this;
  }

  /**
   * @param  string $file
   * @param  string? $vendor
   * @return SrsBaseView
   */
  protected function addScript($file, $vendor = null)
  {
    $path = AgaviConfig::get('app.path') . '/';

    if ($vendor)
    {
      $path .= 'vendor/' . $vendor . '/';
    }
    else
    {
      $path .= 'js/';
    }

    $path .= $file . '.js';

    $this->context->getRequest()->appendAttribute('javascripts', $path);

    return $this;
  }
}